﻿namespace Lr.Core.Validation.Fluent
{
    /// <summary>
    /// Helps building an <see cref="IValidationRule"/>.
    /// </summary>
    public class ValidationRuleBuilder
    {        
        /// <summary>
        /// Gets the <see cref="IValidatable"/> that started the process.
        /// </summary>
        internal IValidatable Validatable { get { return _validatable; } }
        private readonly IValidatable _validatable;

        /// <summary>
        /// Creates a new <see cref="ValidationRuleBuilder"/> object.
        /// </summary>
        /// <param name="validatable">The validatable that starts the process.</param>
        public ValidationRuleBuilder(IValidatable validatable)
        {
            ThrowIf.Null(() => validatable);

            _validatable = validatable;
        }

        /// <summary>
        /// Initiates the building process for a specific <typeparamref name="TValidatable"/>.
        /// </summary>
        /// <typeparam name="TValidatable">The type of the <see cref="IValidatable"/>.</typeparam>
        /// <returns>A <see cref="ValidationBuilder"/> of type <typeparamref name="TValidatable"/>.</returns>
        public ValidationRuleBuilder<TValidatable> For<TValidatable>()
            where TValidatable : IValidatable
        {
            return new ValidationRuleBuilder<TValidatable>(_validatable);
        }

        /// <summary>
        /// Returns a <see cref="String"/> that represents the object.
        /// </summary>
        /// <returns>A <see cref="String"/> that represents the object.</returns>
        public override string ToString()
        {
            return this.ToDebugString();
        }
    }

    /// <summary>
    /// Helps building an <see cref="IValidationRule"/>.
    /// </summary>
    /// <typeparam name="TValidatable">The type of the <see cref="IValidatable"/>.</typeparam>
    public class ValidationRuleBuilder<TValidatable>
        where TValidatable : IValidatable
    {
        /// <summary>
        /// Gets the <see cref="IValidatable"/> that started the process.
        /// </summary>
        internal IValidatable Validatable { get { return _validatable; } }
        private readonly IValidatable _validatable;

        /// <summary>
        /// Creates a new <see cref="ValidationRuleBuilder"/> of <typeparamref name="TValidatable"/> object.
        /// </summary>
        /// <param name="validatable">The validatable that starts the process.</param>
        public ValidationRuleBuilder(IValidatable validatable)
        {
            ThrowIf.Null(() => validatable);

            _validatable = validatable;
        }

        /// <summary>
        /// Continues the building process for a specific <typeparamref name="TValidatable"/>.
        /// </summary>
        /// <param name="errorMessage">The error message to be displayed when the rule fails.</param>
        /// <returns>A <see cref="ValidationBuilderWithErrorMessage"/> of type <typeparamref name="TValidatable"/>.</returns>
        public ValidationRuleBuilderWithErrorMessage<TValidatable> WithErrorMessage(string errorMessage)
        {
            return new ValidationRuleBuilderWithErrorMessage<TValidatable>(this, errorMessage);
        }

        /// <summary>
        /// Returns a <see cref="String"/> that represents the object.
        /// </summary>
        /// <returns>A <see cref="String"/> that represents the object.</returns>
        public override string ToString()
        {
            return this.ToDebugString();
        }
    }
}
